package com.lfy.chat;

import com.lfy.chat.handler.HttpHeadersHandler;
import com.lfy.chat.handler.LfyImServerHandler;
import com.lfy.chat.handler.testHandler;
import com.lfy.commons.init.ApplicationInit;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.util.concurrent.Future;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
/**
 * websocket
 *
 * @author <a href="https://www.lvfeiy.top">吕飞扬</a>
 * @date 2023/10/13 15:53
 */

@Component
@Slf4j
public class WebSocketServer implements ApplicationInit {

    private NioEventLoopGroup boss = new NioEventLoopGroup();
    private NioEventLoopGroup worker = new NioEventLoopGroup();
    private  Channel channel;

    {
        log.info("webSocket create bean ....................");
    }

    @Override
    public void init() {
        this.run();
    }

    @PreDestroy
    public void destroy() {
        Future<?> future = boss.shutdownGracefully();
        Future<?> future1 = worker.shutdownGracefully();
        future.syncUninterruptibly();
        future1.syncUninterruptibly();
        channel.close();
        log.info("close webSocket serverGroup success");
    }
    private void run() {
        ChannelFuture future = new ServerBootstrap().group(boss, worker)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<Channel>() {
                    @Override
                    protected void initChannel(Channel channel) throws Exception {
                        ChannelPipeline pipeline = channel.pipeline();
                        //http解码器
                        pipeline.addLast(new LoggingHandler(LogLevel.INFO));
                        pipeline.addLast(new HttpServerCodec());
                        //对大数据流写提供支持
                        pipeline.addLast(new ChunkedWriteHandler());
                        //对httpMessage进行聚合处理，聚合成Response和Request
                        pipeline.addLast(new HttpObjectAggregator(8192));

                        //自定义处理器
                        pipeline.addLast(new HttpHeadersHandler());
                        pipeline.addLast(new WebSocketServerProtocolHandler("/"));
//                        pipeline.addLast(new testHandler());
                        pipeline.addLast(new LfyImServerHandler());

                    }
                }).bind(3000);

        try {
            channel = future.sync().channel();
            channel.closeFuture().sync();
            log.info("websocket close....");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        WebSocketServer webSocketServer = new WebSocketServer();
        webSocketServer.run();
    }

}
